#ifndef _CHASSIS_INFO_H_
#define _CHASSIS_INFO_H_
#include "types.h"
#include <string>

class  ChassisInfo {
public:
    ChassisInfo() : _length(0), _type(0), _bootupState(0), _powerSupplyState(0), 
                    _thermalState(0), _securityStatus(0), _oemDefined(0), _height(0),
                    _numberOfPowerCords(0), _ceCountN(0), _ceRecordLengthM(0),
                    _containedElement(nullptr){}
    ChassisInfo(UINT8 len, const std::string &manuf, UINT8 type,
                const std::string &version, const std::string &sn, const std::string &tag)
        : _bootupState(0), _powerSupplyState(0),
          _thermalState(0), _securityStatus(0), _oemDefined(0), _height(0),
          _numberOfPowerCords(0), _ceCountN(0), _ceRecordLengthM(0),
          _containedElement(nullptr) { setGeneral(len, manuf, type, version, sn, tag); }
    ~ChassisInfo();

    void        setGeneral(UINT8 len, const std::string& manuf, UINT8 type,
                           const std::string& version, const std::string& sn, 
                           const std::string& tag);
    void        set2_1(UINT8 bootupState, UINT8 powerSupply,
                       UINT8 thermalState, UINT8 securityStatus);
    // ce: Contained Element
    void        setContainedElement(UINT8 count, UINT8 recordLength, const UINT8* ce);

    void        setHeight(UINT8 height) { _height = height; }
    void        setoemDefined(UINT32 oemDefined) { _oemDefined = _oemDefined; }
    void        setNumberOfPowerCords(UINT8 num) { _numberOfPowerCords = num; }
    void        setSkuNumber(const std::string& str) { _skuNumber = str; }

    void        print();

private:
    const char *printType(UINT8 code);
    const char *printLock(UINT8 code);
    const char *printState(UINT8 code);
    const char *printSecurityStatus();
    const char *smbiosStructureType(UINT8 code);
    const char *getBaseBoardType(UINT8 code);
    void        printChassisElements(UINT8 count, UINT8 len, const UINT8 *p);

private:
    // 2.0+
    UINT8       _length;
    std::string _manufacturer;
    UINT8       _type;
    std::string _version;
    std::string _serialNumber;
    std::string _assetTagNumber;
    // 2.1+
    UINT8       _bootupState;
    UINT8       _powerSupplyState;
    UINT8       _thermalState;
    UINT8       _securityStatus;
    // 2.3+
    UINT32      _oemDefined;
    UINT8       _height;
    UINT8       _numberOfPowerCords;
    // ce: Contained Element
    UINT8       _ceCountN;
    UINT8       _ceRecordLengthM;
    UINT8*      _containedElement; // N * M
    // 2.7+
    std::string _skuNumber;
};

#endif